﻿using System;
using System.Collections.Generic;
using base31.Hub.Helpers;

namespace base31.Hub.Models
{
    /// <summary>
    /// Work item inserted when a publish event occurs.
    /// A feed that has new data that needs to be pulled.
    /// The key name of this entity is a GetHashKeyName() hash of the topic URL, so
    /// multiple inserts will only ever write a single entity.
    /// </summary>
    public class FeedToFetch
    {
        public string Topic { get; set; }
        public DateTime Eta { get; set; }
        public int FetchingFailures { get; set; }
        public bool TotallyFailed { get; set; }
        public string SourceKeys { get; set; }
        public string SourceValues { get; set; }
        public int WorkIndex { get; set; }

        /// <summary>
        /// Retrives a FeedToFetch by the topic URL.
        /// </summary>
        /// <param name="topic">The URL for the feed.</param>
        /// <returns>The FeedToFetch or null if it does not exist.</returns>
        public FeedToFetch GetByTopic(string topic)
        {
            return null;
        }

        /// <summary>
        /// Inserts a set of FeedToFetch entities for a set of topics.
        /// Overwrites any existing entities that are already there.
        /// </summary>
        /// <param name="topicList">List of the topic URLs of feeds that need to be fetched.</param>
        /// <param name="sourceDict">Dictionary of sources for the feed. Defaults to an empty dictionary.</param>
        /// <param name="memoryOnly">Only save FeedToFetch records to memory, not to disk.</param>
        /// <returns>The list of FeedToFetch records that was created.</returns>
        public List<FeedToFetch> Insert(List<string> topicList,
                                        Dictionary<string, string> sourceDict = null,
                                        bool memoryOnly = true)
        {
            return null;
        }

        /// <summary>
        /// Reports that feed fetching failed.
        /// This will mark this feed as failing to fetch. This feed will not be
        /// refetched until insert() is called again.
        /// </summary>
        /// <param name="maxFailures">Maximum failures to allow before giving up.</param>
        /// <param name="retryPeriod">Initial period for doing exponential (base-2) backoff.</param>
        public void FetchFailed(int maxFailures = Constants.MAX_FEED_PULL_FAILURES,
                                int retryPeriod = Constants.FEED_PULL_RETRY_PERIOD)
        {

        }

        /// <summary>
        /// The feed fetch has completed successfully.
        /// This will delete this FeedToFetch entity iff the ETA has not changed,
        /// meaning a subsequent publish event did not happen for this topic URL. If
        /// the ETA has changed, then we can safely assume there is a pending Task to
        /// take care of this FeedToFetch and we should leave the entry.
        /// </summary>
        /// <returns>True if the entity was deleted, False otherwise. In the case the
        /// FeedToFetch record never made it into the Datastore (because it only
        /// ever lived in the in-memory cache), this function will return False.</returns>
        public bool Done()
        {
            return true;
        }

        /// <summary>
        /// Enqueues a task to retry fetching this feed.
        /// </summary>
        public void EnqueueRetryTask()
        {
            
        }
    }
}